#include<bits/stdc++.h>
#define int long long
using namespace std;
typedef pair<int,int> pii;
typedef tuple<int,int,int> tpi;
const int I=-1e18;
inline tpi getq(int ls){
  int op,p,q; cin>>op>>p>>q;
  return make_tuple(op,p^ls,q^ls);
}
namespace S2{
  struct matrix{
    array<array<int,3>,3> a;
    matrix(){for(auto &i:a)i.fill(I);}
    inline array<int,3>& operator [](int x){return this->a[x];}
  };
  inline matrix operator *(matrix &a,matrix &b){
    matrix c;
    for(int i=0;i<3;i++)
      for(int j=0;j<3;j++)
        for(int k=0;k<3;k++)
          c[i][j]=max(c[i][j],a[i][k]+b[k][j]);
    return c;
  }
  inline vector<int> operator *(vector<int> &a,matrix &b){
    vector<int> c(3,I);
    for(int j=0;j<3;j++)
      for(int k=0;k<3;k++)
        c[j]=max(c[j],a[k]+b[k][j]);
    return c;
  }
  class segtree{
    private:
      int n;
      vector<pii> B;
      vector<matrix> S;
      inline void pushup(int u){
        S[u]=S[u<<1]*S[u<<1|1];
      }
    public:
      segtree(const vector<matrix> &a){
        n=a.size(),B.resize(n<<2),S.resize(n<<2);
        function<void(int,int,int)> build=[&](int u,int l,int r){
          B[u]=make_pair(l,r);
          if(l==r){S[u]=a[l]; return;}
          int m=l+r>>1;
          build(u<<1,l,m),build(u<<1|1,m+1,r);
          pushup(u);
        };
        build(1,0,n-1);
      }
      void update(int u,int p,const matrix &x){
        if(B[u].first==B[u].second){S[u]=x; return;}
        int m=B[u].first+B[u].second>>1;
        update(u<<1|(p>m),p,x),pushup(u);
      }
      void query(int u,int l,int r,vector<int> &x){
        if(B[u].first>r||B[u].second<l)return;
        if(l<=B[u].first&&B[u].second<=r){x=x*S[u]; return;}
        query(u<<1,l,r,x),query(u<<1|1,l,r,x);
      }
  };
  vector<int> solve(int n,int m,int Q,vector<int> c,vector<vector<int> > a){
    vector<int> r;
    vector<matrix> k(n);
    for(int i=0;i<n;i++){
      for(int j=1;j<=m;j++)
        k[i][j][j]=a[i][j-1];
      k[i][0][0]=k[i][c[i]][0]=k[i][0][c[i]]=a[i][c[i]-1];
    }
    segtree t(k);
    int ls=0;
    auto getr=[&](int l,int r){
      vector<int> a(3,I); a[0]=0;
      t.query(1,l,r,a);
      return ls=a[0];
    };
    r.emplace_back(getr(0,n-1));
    while(Q--){
      int op,p,q; tie(op,p,q)=getq(ls);
      if(op==1){
        p--;
        k[p][0][0]=k[p][c[p]][0]=k[p][0][c[p]]=-1e18;
        c[p]=q;
        k[p][0][0]=k[p][c[p]][0]=k[p][0][c[p]]=a[p][c[p]-1];
        t.update(1,p,k[p]);
      }
      else r.emplace_back(getr(p-1,q-1));
    }
    return r;
  }
}
namespace S5{
  struct matrix{
    array<array<int,6>,6> a;
    matrix(){for(auto &i:a)i.fill(I);}
    inline array<int,6>& operator [](int x){return this->a[x];}
  };
  inline matrix operator *(matrix &a,matrix &b){
    matrix c;
    for(int i=0;i<6;i++)
      for(int j=0;j<6;j++)
        for(int k=0;k<6;k++)
          c[i][j]=max(c[i][j],a[i][k]+b[k][j]);
    return c;
  }
  inline vector<int> operator *(vector<int> &a,matrix &b){
    vector<int> c(6,I);
    for(int j=0;j<6;j++)
      for(int k=0;k<6;k++)
        c[j]=max(c[j],a[k]+b[k][j]);
    return c;
  }
  class segtree{
    private:
      int n;
      vector<pii> B;
      vector<matrix> S;
      inline void pushup(int u){
        S[u]=S[u<<1]*S[u<<1|1];
      }
    public:
      segtree(const vector<matrix> &a){
        n=a.size(),B.resize(n<<2),S.resize(n<<2);
        function<void(int,int,int)> build=[&](int u,int l,int r){
          B[u]=make_pair(l,r);
          if(l==r){S[u]=a[l]; return;}
          int m=l+r>>1;
          build(u<<1,l,m),build(u<<1|1,m+1,r);
          pushup(u);
        };
        build(1,0,n-1);
      }
      void update(int u,int p,const matrix &x){
        if(B[u].first==B[u].second){S[u]=x; return;}
        int m=B[u].first+B[u].second>>1;
        update(u<<1|(p>m),p,x),pushup(u);
      }
      void query(int u,int l,int r,vector<int> &x){
        if(B[u].first>r||B[u].second<l)return;
        if(l<=B[u].first&&B[u].second<=r){x=x*S[u]; return;}
        query(u<<1,l,r,x),query(u<<1|1,l,r,x);
      }
  };
  vector<int> solve(int n,int m,int Q,vector<int> c,vector<vector<int> > a){
    vector<int> r;
    vector<matrix> k(n);
    for(int i=0;i<n;i++){
      for(int j=1;j<=m;j++)
        k[i][j][j]=a[i][j-1];
      k[i][0][0]=k[i][c[i]][0]=k[i][0][c[i]]=a[i][c[i]-1];
    }
    segtree t(k);
    int ls=0;
    auto getr=[&](int l,int r){
      vector<int> a(6,I); a[0]=0;
      t.query(1,l,r,a);
      return ls=a[0];
    };
    r.emplace_back(getr(0,n-1));
    while(Q--){
      int op,p,q; tie(op,p,q)=getq(ls);
      if(op==1){
        p--;
        k[p][0][0]=k[p][c[p]][0]=k[p][0][c[p]]=-1e18;
        c[p]=q;
        k[p][0][0]=k[p][c[p]][0]=k[p][0][c[p]]=a[p][c[p]-1];
        t.update(1,p,k[p]);
      }
      else r.emplace_back(getr(p-1,q-1));
    }
    return r;
  }
}
main(){
  freopen("paint.in","r",stdin);
  freopen("paint.out","w",stdout);
  ios::sync_with_stdio(false);
  cin.tie(0); cout.tie(0);
  int n,m,Q,ls=0; cin>>n>>m>>Q;
  vector<int> c(n);
  for(auto &i:c)cin>>i;
  vector<vector<int> > a(n,vector<int>(m));
  for(auto &i:a)for(auto &j:i)cin>>j;
  if(n<=8||!Q){
    auto solve=[&](int l,int r){
      vector<vector<int> > f(n,vector<int>(m+1,I));
      for(int i=l;i<=r;i++){
        if(i>l)for(int j=1;j<=m;j++)
          f[i][j]=f[i-1][j]+a[i][j-1];
        f[i][0]=(i>l?max(f[i-1][0],f[i-1][c[i]]):0)+a[i][c[i]-1];
        f[i][c[i]]=max(f[i][c[i]],(i>l?f[i-1][0]:0)+a[i][c[i]-1]);
      }
      return f[r][0];
    };
    cout<<(ls=solve(0,n-1))<<endl;
    while(Q--){
      int op,p,q; tie(op,p,q)=getq(ls);
      if(op==1)c[p-1]=q;
      else cout<<(ls=solve(p-1,q-1))<<'\n';
    }
  }
  else if(m==2){
    auto r=S2::solve(n,m,Q,c,a);
    for(int i:r)cout<<i<<'\n';
  }
  else{
    auto r=S5::solve(n,m,Q,c,a);
    for(int i:r)cout<<i<<'\n';
  }
  return 0;
}